package com.develop.mybluetooth

import android.Manifest
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothGattService
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.Settings
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.animation.Animation
import android.view.animation.LinearInterpolator
import android.view.animation.RotateAnimation
import android.widget.Toast
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.view.GravityCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentTransaction
import androidx.recyclerview.widget.LinearLayoutManager
import com.develop.bluetoothlib.MyBluetooth
import com.develop.bluetoothlib.entity.MyBluetoothDevice
import com.develop.bluetoothlib.exception.BluetoothException
import com.develop.bluetoothlib.inter.BleNotifyCallBack
import com.develop.bluetoothlib.inter.ConnectCallBack
import com.develop.bluetoothlib.inter.ScanCallBack
import com.develop.bluetoothlib.operator.abstra.Sender
import com.develop.mybluetooth.databinding.ActivityMainBinding
import com.develop.mybluetooth.fragment.SPPFragment
import com.develop.mybluetooth.adapter.ScanAdapter
import com.develop.mybluetooth.fragment.BLEServiceListFragment
import dismiss
import showLoading
import t

class MainActivity : AppCompatActivity() {

    private val list: MutableList<MyBluetoothDevice> = ArrayList()
    private var adapter: ScanAdapter? = null
    private var bluetoothType = 0
    private var mMyBluetooth: MyBluetooth? = null
    private lateinit var drawerToggle: ActionBarDrawerToggle // 新增同步开关

    private var binding : ActivityMainBinding ?= null

    private var sppFragment : SPPFragment? = null
    private var bleServiceListFragment : BLEServiceListFragment? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding?.root)


        adapter = ScanAdapter()
        binding?.recyclerViewScan?.setLayoutManager(LinearLayoutManager(this))
        binding?.recyclerViewScan?.setAdapter(adapter)
        sppFragment = SPPFragment()
        bleServiceListFragment = BLEServiceListFragment()
        loadFragment(bleServiceListFragment)

        setupToolbar()
        setupDrawerToggle() // 新增同步配置
        initListener()
        initBluetooth()
        checkPermissionAndScan{  }

    }

    private fun loadFragment(fragment: Fragment?) {
        val currentFragment = supportFragmentManager.findFragmentById(R.id.fragment_container)
        if (currentFragment === fragment) {
           return
        }

        fragment?.let {
            val transaction: FragmentTransaction = supportFragmentManager.beginTransaction()
            transaction.replace(R.id.fragment_container, fragment)
            transaction.addToBackStack(null) // 可选：添加到返回栈
            transaction.commit()
        }
    }


    // 配置工具栏和同步开关
    private fun setupToolbar() {
        setSupportActionBar(binding?.toolbarMain)
        supportActionBar?.setDisplayHomeAsUpEnabled(true)
    }

    // 新增：配置抽屉开关同步
    private fun setupDrawerToggle() {
        drawerToggle = ActionBarDrawerToggle(
            this,
            binding?.drawerLayout,
            binding?.toolbarMain,
            R.string.drawer_open,
            R.string.drawer_close
        ).apply {
            syncState() // 同步按钮状态
        }
        binding?.drawerLayout?.addDrawerListener(drawerToggle)
    }
    // 控制右侧栏开关
    private fun toggleRightDrawer() {
        if (binding?.drawerLayout?.isDrawerOpen(GravityCompat.END) == true) {
            binding?.drawerLayout?.closeDrawer(GravityCompat.END)
        } else {
            binding?.drawerLayout?.openDrawer(GravityCompat.END)
        }
    }


    // 在工具栏添加右侧菜单按钮
    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        menuInflater.inflate(R.menu.main_menu, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.menu_right -> toggleRightDrawer()
        }
        return super.onOptionsItemSelected(item)
    }

    private fun initListener() {
        adapter?.setOnItemClickListener { adapter, _: View?, i: Int ->
            val device = list[i]
            //调用连接器连接蓝牙设备

            showLoading()
            mMyBluetooth?.connect(device, object : ConnectCallBack {
                override fun onConnecting() {
                    addMessage("连接中...",true)
                }

                override fun onConnected(sender: Sender?, bluetoothDevice: BluetoothDevice?) {
                    runOnUiThread {
                        try {
                            binding?.tvConnectedName?.text = bluetoothDevice?.name.toString()
                            binding?.tvConnectedStatus?.text = "Connected"
                            //获取服务
//                        bluetoothDevice.connectGatt()
                        }catch (e : SecurityException){
                            Log.i(TAG, "onConnected " + e.message)
                        }
                        toggleRightDrawer()
                        dismiss()
                        t("连接成功")
                        addMessage("连接成功",true)

                    }

                }

                override fun onDisConnecting() {
                    runOnUiThread {
                        addMessage("断开连接中...",true)
                        dismiss()
                    }
                }

                override fun onDisConnected() {
                    runOnUiThread {
                        binding?.tvConnectedStatus?.text = "DisConnected"
                        addMessage("已断开连接",true)
                        dismiss()
                        t("已断开连接")
                    }
                }

                override fun onError(errorType: Int, errorMsg: String) {
                    runOnUiThread {
                        addMessage("连接失败 $errorMsg",true)
                        dismiss()
                        t(errorMsg)
                    }

                } //低功耗蓝牙才需要BleNotifyCallBack
                //经典蓝牙可以只调两参方法connect(BluetoothDevice device, ConnectCallBack connectCallBack)
            }, object : BleNotifyCallBack {
                override fun onNotifySuccess() {
                    Log.i(TAG, "打开通知成功")
                }

                override fun onNotifyFailure(bleException: BluetoothException) {
                    Log.i(TAG, "打开通知失败：" + bleException.message)
                }

                override fun onDiscoverServices(services: MutableList<BluetoothGattService>?) {
                    bleServiceListFragment?.addServices(services)

                }
            })
        }


        binding?.llBle?.setOnClickListener {
            Log.e( TAG,"选择BLE")
            bluetoothType = MyBluetoothDevice.DEVICE_TYPE_LE
            binding?.drawerLayout?.closeDrawers()
            binding?.tvScanType?.text = getString(R.string.s_scan_ble)
            list.clear()
            adapter?.notifyDataSetChanged()

            loadFragment(bleServiceListFragment)
        }

        binding?.llSpp?.setOnClickListener {
            Log.e( TAG,"选择SPP")
            bluetoothType = MyBluetoothDevice.DEVICE_TYPE_CLASSIC
            binding?.drawerLayout?.closeDrawers()
            binding?.tvScanType?.text = getString(R.string.s_scan_spp)
            list.clear()
            adapter?.notifyDataSetChanged()
            loadFragment(sppFragment)

        }

        binding?.llRefresh?.setOnClickListener {
            //默认是BLE
            binding?.ivLoadingOther?.setAnimation(getImgAnimation())
            binding?.ivLoadingOther?.startAnimation(getImgAnimation())
            checkPermissionAndScan{scan()}
        }

        binding?.btnDisconnect?.setOnClickListener {
            mMyBluetooth?.release()
        }

        binding?.tvConnectedStatus?.setOnClickListener {
            if(mMyBluetooth?.isConnected == true){
                mMyBluetooth?.release()
                binding?.tvConnectedStatus?.text = "DisConnected"
            }
        }
    }


    private fun addMessage(msg  : String, isSent : Boolean){
        val currentFragment = supportFragmentManager.findFragmentById(R.id.fragment_container)
        if (currentFragment is SPPFragment) {
            sppFragment?.addMessage(msg,isSent)
        }
//        else if (currentFragment is BLEConsoleFragment) {
//            bleConsoleFragment?.addMessage(msg,isSent)
//        }
    }

    private var mRotateAnimation: RotateAnimation? = null

    private fun getImgAnimation(): Animation? {
        if (mRotateAnimation == null) {
            mRotateAnimation = RotateAnimation(
                0f,
                360f,
                Animation.RELATIVE_TO_SELF,
                0.5f,
                Animation.RELATIVE_TO_SELF,
                0.5f
            )
            val lin = LinearInterpolator()
            mRotateAnimation?.interpolator = lin
            mRotateAnimation?.duration = 1000 //设置动画持续时间
            mRotateAnimation?.setRepeatCount(-1) //设置重复次数
            mRotateAnimation?.fillAfter = true //动画执行完后是否停留在执行完的状态
            mRotateAnimation?.startOffset = 10 //执行前的等待时间
        }
        return mRotateAnimation
    }

    override fun onDestroy() {
        super.onDestroy()

        mMyBluetooth?.release()
    }


    private val isAboveAndroid12: Boolean
        get() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S

    private fun hasPermission(permission: String): Boolean {
        return ActivityCompat.checkSelfPermission(
            this,
            permission
        ) == PackageManager.PERMISSION_GRANTED
    }


    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        when (requestCode) {
            REQUEST_CODE_SCAN_BT -> {
                var allGranted = true
                for (result in grantResults) {
                    if (result != PackageManager.PERMISSION_GRANTED) {
                        allGranted = false
                        break
                    }
                }
                if (allGranted) {
                    initBluetooth()
                } else {
                    // 处理权限被拒绝的情况
                    showPermissionDeniedDialog()
                }
            }
        }

    }
    private fun showPermissionDeniedDialog() {
        AlertDialog.Builder(this)
            .setTitle("权限被拒绝")
            .setMessage("您已拒绝权限，请在设置中启用蓝牙权限")
            .setPositiveButton("去设置") { _, _ ->
                val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
                intent.data = Uri.fromParts("package", packageName, null)
                startActivity(intent)
            }
            .setNegativeButton("取消", null)
            .show()
    }

    private fun checkPermissionAndScan(unit: ()->Unit) {
        // Android 12+ 需要请求 BLUETOOTH_SCAN 和 BLUETOOTH_CONNECT
        val permissionsToRequest = mutableListOf<String>()

        if(isAboveAndroid12){
            if (ContextCompat.checkSelfPermission(
                    this,
                    Manifest.permission.BLUETOOTH_SCAN
                ) != PackageManager.PERMISSION_GRANTED
            ) {
                permissionsToRequest.add(Manifest.permission.BLUETOOTH_SCAN)
            }
            if (ContextCompat.checkSelfPermission(
                    this,
                    Manifest.permission.BLUETOOTH_CONNECT
                ) != PackageManager.PERMISSION_GRANTED
            ) {
                permissionsToRequest.add(Manifest.permission.BLUETOOTH_CONNECT)
            }
        }

        // 请求旧权限（BLUETOOTH + ACCESS_FINE_LOCATION）
        if (ContextCompat.checkSelfPermission(
                this,
                Manifest.permission.BLUETOOTH
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            permissionsToRequest.add(Manifest.permission.BLUETOOTH)
        }
        if (ContextCompat.checkSelfPermission(
                this,
                Manifest.permission.ACCESS_FINE_LOCATION
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            permissionsToRequest.add(Manifest.permission.ACCESS_FINE_LOCATION)
        }

        if (permissionsToRequest.isNotEmpty()) {
            // 动态请求缺失的权限
            ActivityCompat.requestPermissions(
                this,
                permissionsToRequest.toTypedArray(),
                REQUEST_CODE_SCAN_BT
            )
        } else {
           unit()
        }
    }

    private fun initBluetooth(){
        bluetoothType = MyBluetoothDevice.DEVICE_TYPE_LE
        //填写设备的UUID
        //低功耗蓝牙才需要如下配置BleConfig,经典蓝牙不需要new HBluetooth.BleConfig()
        mMyBluetooth = MyBluetooth.getInstance()
        mMyBluetooth?.enableBluetooth()

//        val bleConfig = BleConfig()
//        bleConfig.withServiceUUID("0000fe61-0000-1000-8000-00805f9b34fb")
//            .withWriteCharacteristicUUID("0000fe61-0000-1000-8000-00805f9b34fb")
//            .withNotifyCharacteristicUUID("0000fe61-0000-1000-8000-00805f9b34fb") //指定UUID扫描，即扫描过滤掉非当前设置的UUID的设备
//            //.setScanFilterServerUUIDs(new UUID[]{UUID.fromString("0000fe61-0000-1000-8000-00805f9b34fb")})
//            //.liveUpdateScannedDeviceName(true)
//            //命令长度大于20个字节时是否分包发送，默认false,分包时可以调两参方法设置包之间发送间隔
//            //默认false,注释部分为默认值
//            //.splitPacketToSendWhenCmdLenBeyond(false)
//            //.useCharacteristicDescriptor(false)
//            //连接后开启通知的延迟时间，单位ms，默认200ms
//            //.notifyDelay(200)
//            .setMtu(200, object : BleMtuChangedCallback {
//                override fun onSetMTUFailure(realMtuSize: Int, bleException: BluetoothException) {
//                    Log.i(
//                        TAG,
//                        "bleException:" + bleException.message + "  realMtuSize:" + realMtuSize
//                    )
//                }
//
//                override fun onMtuChanged(mtuSize: Int) {
//                    Log.i(TAG, "Mtu set success,mtuSize:$mtuSize")
//                }
//            })
//
//        //开启蓝牙功能
//        myBluetooth?.bleConfig = bleConfig
    }

    private fun scan() {
        if (list.isNotEmpty()) {
            list.clear()
            adapter?.notifyDataSetChanged()
        }

        //有设置扫描时间的扫描，时间到会自动结束扫描
        scanWithTimeUse(bluetoothType)
    }


    private fun scanWithTimeUse(bleType: Int) {
        //扫描蓝牙设备，扫描6秒就自动停止扫描
        mMyBluetooth?.scan(bleType, 6000, object : ScanCallBack {
            override fun onScanStart() {
                Log.i(TAG, "开始扫描")
            }

            override fun onScanning(
                scannedDevices: List<MyBluetoothDevice>,
                currentScannedDevice: MyBluetoothDevice
            ) {
//                Log.i(TAG, "扫描中");
                if (scannedDevices.isNotEmpty()) {
                    list.clear()
                    list.addAll(scannedDevices)
                    adapter?.submitList(list)
                }
            }

            override fun onError(errorType: Int, errorMsg: String) {
                Log.e(
                    TAG,
                    "errorType:$errorType  errorMsg:$errorMsg"
                )
            }

            override fun onScanFinished(bluetoothDevices: List<MyBluetoothDevice>) {
                Log.i(TAG, "扫描结束 onScanFinished " + bluetoothDevices.size)
                binding?.ivLoadingOther?.clearAnimation()

                Toast.makeText(this@MainActivity, "扫描结束", Toast.LENGTH_LONG).show()
                if (bluetoothDevices.isNotEmpty()) {
                    list.clear()
                    list.addAll(bluetoothDevices)
                    adapter?.submitList(list)
                }
            }
        })
    }

    companion object {
        private const val TAG = "BL log"

        private const val REQUEST_CODE_SCAN_BT = 100
    }
}
